using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FytSoa.Application.Sys;
using FytSoa.Common.Utils;
using FytSoa.Domain.Core.Cache;
using FytSoa.Domain.Core.Jwt;
using FytSoa.Domain.Core.Jwt.Model;
using FytSoa.Domain.Core.Result;
using FytSoa.DynamicApi.Attributes;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace FytSoa.Application.Operator
{
    /// <summary>
    /// 操作人服务
    /// </summary>
    [ApiExplorerSettings(GroupName = "v1")]
    public class OperatorService : IOperatorService
    {
        readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ISysAdminService _adminService;
        public OperatorService(IHttpContextAccessor httpContextAccessor
        ,ISysAdminService adminService) {
            _httpContextAccessor = httpContextAccessor;
            _adminService = adminService;
        }
        
        public bool IsAuthorize => _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;

        public OperatorUser User => IsAuthorize ? new OperatorUser()
        {
            Id= long.Parse(_httpContextAccessor.HttpContext.User.Claims.FirstOrDefault(m=>m.Type==nameof(OperatorUser.Id))?.Value),
            Username= _httpContextAccessor.HttpContext.User.Claims.FirstOrDefault(m => m.Type == nameof(OperatorUser.Username))?.Value
        } : new OperatorUser();

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="loginParam"></param>
        /// <returns></returns>
        public async Task<ApiResult<LoginTokenDto>> LoginAsync(LoginParam loginParam)
        {
            var loginRes = await _adminService.LoginAsync(loginParam);
            if (loginRes.Code!=200)
            {
                return JResult<LoginTokenDto>.Error(loginRes.Message);
            }
            var token = JwtAuthService.IssueJwt(new JwtToken () { Id = loginRes.Data.Id, FullName = loginRes.Data.FullName, Role = "Admin", Time = DateTime.Now });
            return JResult<LoginTokenDto>.Success(new LoginTokenDto(){ accessToken = token});
        }

        /// <summary>
        /// 查询登录人信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<OperatorUser>> UserInfo()
        {
            var paramToken=_httpContextAccessor.HttpContext?.Request.Headers["accessToken"].ToString();
            var token = JwtAuthService.SerializeJwt(paramToken);
            var model = await _adminService.GetAsync(token.Id);
            return JResult<OperatorUser>.Success(new OperatorUser()
            {
                Id = model.Data.Id,
                Username = model.Data.FullName,
                Avatar = model.Data.HeadPic
            });
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ApiResult<int> Logout()
        {
            var paramToken=_httpContextAccessor.HttpContext?.Request.Headers["accessToken"].ToString();
            //加入到黑名单中，在中间件判断 token是否在黑名单，如果在，则默认为假的token，重新登录
            var blackList = RedisService.Instance.Get<List<string>>(KeyUtils.JWTBLACKLIST);
            blackList.Add(paramToken);
            RedisService.Instance.SetJson(KeyUtils.JWTBLACKLIST,blackList);
            return JResult<int>.Success();
        }
    }
}